(function($) {
	window.showTip = (function(){
	    var $tip = $('<div class="message"></div>');
	    var timeout;
	    return function(message){
	        clearTimeout(timeout);
	        $tip.html(message).appendTo(document.body);
	        timeout = setTimeout(function(){
	            $tip.remove();
	        }, 5000);
	    };
	})();
	
	$('div#container').mask("loading sf2 files, Please waiting...");
	var tempoFactor = 1;
	var tempo = 100;
	var rPlayer=new jweb.util.RhythmPlayer();
	var console=new jweb.util.Console();
	//not use wavetable now
	//var bridge=new jweb.util.SynthBridge();
	var synthesizer = new jweb.util.Synthesizer();
	//var waveTable = new jweb.util.WaveTable();
	//var visualizer = new jweb.util.Visualizer();
	var midiHub = new jweb.gdgsuzhou.webmusic.MidiHub();
	/* Style */
	window.$styles = $('#style input');
    $styles.on('change', function(){
        var style = $styles.filter(':checked').val();
        var values ;
        var names ;
        
        if('epic'==style){
        	values = [0, 1];
        	names = ['Stay Hot', 'Mad Heart'];
        }
        else if('electro'==style){
        	values = [2, 2];
        	names = ['Electro Demo', 'Electro Demo'];
        }
        else if('chinese'==style){
        	values = [3, 3];
        	names = ['CHN Demo', 'CHN Demo'];
        }
        
        $('select[name="pattern"] option').each(function(index){
        	$(this).val(values[index]);
        	$(this).html(names[index]);
        });
    });
	/*master tempo*/
	window.$masterTempo = $('#tempo').tempo({
		onchange : function(value) {
			tempo=value;
			rPlayer.setTempo(parseInt(value*tempoFactor));
		}
	});
	/*master vol*/
	window.$masterVol = $('#master .knob-master').knob({
		defaultValue:75,
		valueRange: [0, 127],
		onchange : function(value) {
			synthesizer.onUpdateVolume(value);
		}
	});
	
	/**************** OSC1 Vol ****************/
	window.$osc1Vol = $('#osc1 .knob-vol').knob({
		defaultValue:75,
		valueRange: [0, 127],
		onchange : function(value) {
			synthesizer.onUpdateOsc1Mix(value);
		}
	});
	/*osc1 wavform*/
	window.$osc1Waveform  = $('#osc1 .knob-wave').knob2({
	    onchange: function(value){
	       if('sine'==value) synthesizer.onUpdateOsc1Wave(0);
	       else if('triangle'==value) synthesizer.onUpdateOsc1Wave(3);
	       else if('square'==value) synthesizer.onUpdateOsc1Wave(1);
	       else if('saw'==value) synthesizer.onUpdateOsc1Wave(2);
	    }
	});
	/*osc1 attack*/
	window.$osc1Attack = $('#osc1 .knob-attack').knob({
		valueRange: [0, 50],
		defaultValue:0,
		onchange : function(value) {
			synthesizer.onUpdateEnvA1(value);
		}
	});
	/*osc1 release*/
	window.$osc1Release = $('#osc1 .knob-release').knob({
		defaultValue:0,
		valueRange: [0, 50],
		onchange : function(value) {
			synthesizer.onUpdateEnvR1(value);
		}
	});
	/*OSC1 detune*/
	window.$osc1Detune = $('#osc1 .range').range({
		defaultValue:0,
		valueRange: [-1200, 1200],
		onchange : function(value) {
			synthesizer.onUpdateOsc1Detune(-1*value);
		}
	});
	//osc1 FM waveform 
	window.$osc1FmWaveform  = $('#osc1 .knob-fm-wave').knob2({
	    onchange: function(value){
	    	window.PageBus.publish(constants.topicLog, {level:'DEBUG', waveform:value});	
	       if('sine'==value) synthesizer.onUpdateModWaveform1(0);
	       else if('triangle'==value) synthesizer.onUpdateModWaveform1(3);
	       else if('square'==value) synthesizer.onUpdateModWaveform1(1);
	       else if('saw'==value) synthesizer.onUpdateModWaveform1(2);
	    }
	});
	/*osc1 FM freq*/
	window.$osc1fmq = $('#osc1 .knob-fm-freq').knob({
        valueRange: [0, 100],
        defaultValue: 10,
        onchange: function(val){
        	window.PageBus.publish(constants.topicLog, {level:'DEBUG', freq:val});	
        	synthesizer.onUpdateModFrequency1(val);
        }
    });
	/*osc1 FM depth*/
	window.$osc1fmq = $('#osc1 .knob-fm-depth').knob({
        valueRange: [0, 100],
        defaultValue: 10,
        onchange: function(val){
        	window.PageBus.publish(constants.topicLog, {level:'DEBUG', depth:val});
        	synthesizer.onUpdateModOsc1(val);
        }
    });
	/*osc1 Filter cuteoff*/
	window.$osc1flcuteoff = $('#osc1 .knob-filter-cutoff').knob({
        valueRange: [0, 1],
        defaultValue: 10,
        onchange: function(val){
        	val = val * 10 +4;
        	synthesizer.onUpdateFilterCutoff1(val);
        }
    });
	/*osc1 Filter Q*/
	window.$osc1flq = $('#osc1 .knob-filter-q').knob({
        valueRange: [0, 200],
        defaultValue: 10,
        onchange: function(val){
        	synthesizer.onUpdateFilterQ1(val);
        }
    });
	/*osc1 Filter mod*/
	window.$osc2flmod = $('#osc1 .knob-filter-mod').knob({
        valueRange: [0, 200],
        defaultValue: 10,
        onchange: function(val){
        	synthesizer.onUpdateFilterMod1(val);
        }
    });
	/*osc1 Filter resonance*/
	window.$osc2flreson = $('#osc1 .knob-filter-resonance').knob({
        valueRange: [0, 200],
        defaultValue: 10,
        onchange: function(val){
        	synthesizer.onUpdateFilterMod1(val);
        }
    });
	
	/****************OSC2 Vol****************/
	window.$osc2Vol = $('#osc2 .knob-vol').knob({
		defaultValue:75,
		valueRange: [0, 100],
		onchange : function(value) {
			synthesizer.onUpdateOsc2Mix(value);
		}
	});
	/*osc2 wavform*/
	window.$osc2Waveform  = $('#osc2 .knob-wave').knob2({
	    onchange: function(value){
	       if('sine'==value) synthesizer.onUpdateOsc2Wave(0);
	       else if('triangle'==value) synthesizer.onUpdateOsc2Wave(3);
	       else if('square'==value) synthesizer.onUpdateOsc2Wave(1);
	       else if('saw'==value) synthesizer.onUpdateOsc2Wave(2);
	    }
	});
	/*osc2 attack*/
	window.$osc2Attack = $('#osc2 .knob-attack').knob({
		valueRange: [0, 50],
		defaultValue:5,
		onchange : function(value) {
			window.PageBus.publish(constants.topicLog, {level:'DEBUG', a:value});
			synthesizer.onUpdateEnvA2(value);
		}
	});
	/*osc2 release*/
	window.$osc1Release = $('#osc2 .knob-release').knob({
		valueRange: [0, 50],
		defaultValue:7,
		onchange : function(value) {
			synthesizer.onUpdateEnvR2(value);
		}
	});
	/*osc2 detune*/
	window.$osc2Detune = $('#osc2 .range').range({
		defaultValue:0,
		valueRange: [-1200, 1200],
		onchange : function(value) {
			synthesizer.onUpdateOsc2Detune(-1*value);
		}
	});
	/*osc2 FM Freq*/
	window.$osc2fmq = $('#osc2 .knob-fm-freq').knob({
        valueRange: [0, 100],
        defaultValue: 10,
        onchange: function(val){
        	window.PageBus.publish(constants.topicLog, {level:'DEBUG', freq:val});
        	synthesizer.onUpdateModFrequency2(val);
        }
    });
	window.$osc2FmWaveform = $('#osc2 .knob-fm-wave').knob2({
		onchange : function(value) {
			window.PageBus.publish(constants.topicLog, {level:'DEBUG', waveform:value});	
			 if('sine'==value) synthesizer.onUpdateModWaveform2(0);
		     else if('triangle'==value) synthesizer.onUpdateModWaveform2(3);
		     else if('square'==value) synthesizer.onUpdateModWaveform2(1);
		     else if('saw'==value) synthesizer.onUpdateModWaveform2(2);
		}
	});
	/*osc2 FM depth*/
	window.$osc2fmq = $('#osc2 .knob-fm-depth').knob({
        valueRange: [0, 100],
        defaultValue: 10,
        onchange: function(val){
        	window.PageBus.publish(constants.topicLog, {level:'DEBUG', depth:val});
        	synthesizer.onUpdateModOsc2(val);
        }
    });
	/*osc2 Filter cuteoff*/
	window.$osc2flcuteoff = $('#osc2 .knob-filter-cutoff').knob({
        valueRange: [0, 1],
        defaultValue: 10,
        onchange: function(val){
        	val = val *10 +4;
        	synthesizer.onUpdateFilterCutoff2(val);
        }
    });
	/*osc2 Filter Q*/
	window.$osc2flq = $('#osc2 .knob-filter-q').knob({
        valueRange: [0, 200],
        defaultValue: 10,
        onchange: function(val){
        	synthesizer.onUpdateFilterQ2(val);
        }
    });
	/*osc2 Filter mod*/
	window.$osc2flmod = $('#osc2 .knob-filter-mod').knob({
        valueRange: [0, 200],
        defaultValue: 10,
        onchange: function(val){
        	synthesizer.onUpdateFilterMod2(val);
        }
    });
	/*osc2 Filter resonance*/
	window.$osc2flreson = $('#osc2 .knob-filter-resonance').knob({
        valueRange: [0, 200],
        defaultValue: 10,
        onchange: function(val){
        	synthesizer.onUpdateFilterMod2(val);
        }
    });
	
	/*arp vol*/
	$('#arp .knob[knob=vol]').knob({
        valueRange: [0, 100],
        defaultValue: 75,
        onchange: function(val){
            //synthesizer.onUpdateOsc2Mix(val);
        	window.showTip('TODO');
        }
    });
	$('#arp .knob[knob=note-length]').knob({
        valueRange: [0.0, 1.0],
        defaultValue: 1,
        onchange: function(val){
        	if(val<0.4)val = 0.4;
        	rPlayer.noteLength = val;
        }
    });
	$('#arp .knob[knob=swing]').knob({
        valueRange: [0, 1],
        defaultValue: 1,
        onchange: function(val){
        	window.showTip('TODO');
        }
    });
	$('#arp .knob[knob=rev]').knob({
        valueRange: [0, 100],
        defaultValue: 32,
        onchange: function(val){
        	synthesizer.onUpdateReverb(val);
        }
    });
	$('#arp .knob[knob=delay]').knob({
        valueRange: [0, 1],
        defaultValue: 0.5,
        onchange: function(val){
        	synthesizer.onUpdateDelay(val);
        }
    });
	/*bass vol*/
	$('#bassline .vol').knob({
        valueRange: [0, 100],
        defaultValue: 10,
        onchange: function(val){
            //synthesizer.onUpdateOsc1Mix(val);
        	window.showTip('TODO');
        }
    });
    
	window.$mod = $('#arp .mod .knob').knob2({
		values : [ 'pattern', 'random' ],
		defaultValue : 'pattern',
		onchange : function(value) {
			//console.log(value);
		}
	});
	window.$arptempo = $('#arp .arptempo').knob2({
		values : [ 0.5, 1, 2 ],
		defaultValue : 1,
		onchange : function(value) {
			tempoFactor = value;
			rPlayer.setTempo(parseInt(tempo*tempoFactor));
		}
	});

	$('#beatbeast .record').on('click', function() {
		var $this = $(this);
		if ($this.hasClass('unrecord')) {
			$this.removeClass('unrecord');
			//console.log('record');
		} else {
			$this.addClass('unrecord');
			//console.log('unrecord');
		}
	});

	$('#beatbeast .play').on('click', function() {
		var $this = $(this);
		var rpIndex = $('select[name="pattern"]').val();
		var playPattern = allPatterns[rpIndex];
		if ($this.hasClass('stop')) {
			$this.removeClass('stop');
			rPlayer.play(playPattern, true);
		} else {
			$this.addClass('stop');
			rPlayer.play(playPattern, true);
		}
	});
	
	$('select[name="pattern"]').on('change', function(){
		var rpIndex = $('select[name="pattern"]').val();
		var playPattern = allPatterns[rpIndex];
		rPlayer.setPattern(playPattern);
	});
	$('div#container').unmask();
})(jQuery);